Tip |
As a multithread program has several threads, it is possible that one thread reads a variable while other thread is writing the variable. In order to eliminate this problem, each thread must have its own set of variables to operate. Como un programa multi-tarea tiene varias threads, es posible que una de las threads lea una variable mientras otra thread está escribiendo la variable. A fin de eliminar este problema, cada thread debe tener su propio conjunto de variables para operar. |
Exchange Variables |
An exchange variable is used to move information among threads. Typically, a multi-thread program must have a minimum number of exchange variables. At least there must be one exchange variable to monitor the status of a working thread. Another exchange variable can be used to stop the working thread. Una variable de intercambio es usada para mover información entre threads. Típicamente, un programa multi-tarea debe tener un mínimo número de variables de intercambio. Al menos debe haber una variable de intercambio para monitorear el estado de la working thread. Otra variable de intercambio se puede usar para detener la working thread. |
Interlocked Functions |
Microsoft Windows provides a set of functions to exchange integer values among threads. The interlocked functions prevent more than one thread from using the same variable simultaneously.These functions are illustrated in the following table. Note that you need these functions only when the variable is used by more than one thread. These functions provide the fastest method to exchange information among threads. In the example below, the share variable is declared as volatile to prevent the compiler to perform any optimization that may prevent that these functions work properly. Microsoft Windows proporciona un conjunto de funciones para intercambiar valores enteros entre threads. Estas funciones previenen que más de una thread use la misma variable simultáneamente. Estas funciones son ilustradas en la tabla siguiente. Note que usted necesita estas funciones solamente cuando la variable es usada por más de una thread. Estas funciones proporcionar el método más rápido para intercambiar información entre threads. En el ejemplo de abajo, a variable compartida es declarada como volatile para prevenir que el compilador realice algún un tipo de optimización previniendo que estas funciones operen correctamente. |
Tip |
The following example illustrates how to use InterlockedExchangeAdd. El ejemplo siguiente ilustra cómo usar InterlockedExchangeAdd. |
Program.h |
class Program : public Win::Dialog { public: Program() { count = 0; hThread = NULL; } ~Program() { } HANDLE hThread static unsigned WINAPI ThreadFunc(LPVOID param); voltile int count; ... }; |
Program.cpp |
void Program::Window_Open(Win::Event& e) { unsigned int threadId; hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, (LPVOID)this, 0, &threadId); } void Program::btIncrease_Click(Win::Event& e) { ::InterlockedExchangeAdd(&count, 2); } void Program::btDecrease_Click(Win::Event& e) { ::InterlockedExchangeAdd(&count, -2); } unsigned WINAPI Program::ThreadFunc(LPVOID param) { Program* program = (Program*)param; ::InterlockedExchangeAdd(&program->count, 20); .... } |
Tip |
Microsoft warns that the parameters for some these functions must be aligned on a 32-bit boundary; otherwise, the function will behave unpredictably. In the example below, the first variable (n) has a size of one byte; therefore the next variable (x) is not aligned on a 32-bit boundary. Always checks the documentation online to be sure, you are using these functions properly. Microsoft advierte que los parámetros de algunas de estas funciones deben están alineados en límites de 32 bits; de otra forma, la función se comportará en forma impredecible. En el ejemplo de abajo, la primera variable (c) tiene un tamaño de un byte; por lo tanto la próxima variable (x) no está alineada en una frontera de 32 bits. Siempre verifique la documentación en línea para estar seguro que usted está usando estas funciones apropiadamente. |
Program.h |
struct { char n; int x; // This variable is not aligned on a 32-bit boundary }; |
C++ 11 atomic |
Starting in version 11, the language C++ supports atomic values. They are a set of classes and template classes to create data types that support atomic operations. See program below. Always try to use atomic values instead of using a mutex. The program below checks at runtime if it is possible to obtain exclusive access to the variable a using atomic. A partir de la versión 11, el lenguaje C++ suporta los valores atómicos. Esto son un conjunto de clases y clases plantilla para crear tipos de datos que trabajen en forma atómica. Ver el programa debajo. Siempre trate de usar valores atómicos en lugar de usar un mutex. El programa de abajo checa en el momento de ejecución si es posible obtener acceso exclusivo a la variable a usando atomic. |
Program.cpp |
#include <atomic> #include <mutex> void Program::SomeFunction() { atomic_int n; //___________________________________ Option 1. Try atomic atomic_int n; n = 0; // n.store(0); n++; if (n.is_lock_free()) { } //____________________________________ Option 2. Use mutex instead std::mutex mx; //__________ n = 0 mx.lock(); n = 0; mx.unlock(); //___________ n++ mx.lock(); n++; mx.unlock(); } |
C# System.Threading.Interlocked |
The C# language provides the Interlocked class to perform atomic operations with integer values as shown in the program below. The Interlocked class provides also some methods to perform atomic operations on Double values: CompareExchange and Exchange. El lenguaje de C# proporciona la clase Interlocked para realizar operaciones atómicas con valores enteros cómo se muestra en el programa de abajo. La clase Interlocked propociona algunos métodos para realizar operaciones atómicas con valores Double: CompareExchange y Exchange. |
Program.cs |
static int x = 0; int y = System.Threading.Interlocked.Add(ref x, 5); // x += 5; y = x; y = System.Threading.Interlocked.Increment(ref x); // x++; y = x; y = System.Threading.Interlocked.Decrement(ref x); // x--; y = x; |